package com.hll.servlet.user;

import com.alibaba.fastjson.JSONArray;
import com.hll.pojo.Role;
import com.hll.pojo.User;
import com.hll.service.role.RoleService;
import com.hll.service.role.RoleServiceImpl;
import com.hll.service.user.UserService;
import com.hll.service.user.UserServiceImpl;
import com.hll.utils.Constants;
import com.hll.utils.PageSupport;
import com.mysql.jdbc.StringUtils;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 用户数据操作
 *
 * @author: Mr.Hu
 * @create: 2021-03-08 11:08
 */
public class UserServlet extends HttpServlet {
  @Override
  protected void doGet(HttpServletRequest req, HttpServletResponse resp)
      throws ServletException, IOException {
    // 密码中有两种类型请求 - 查看旧密码是否正确(ajax) - 更新密码(form)  /js/pwdmodify.js
    String method = req.getParameter("method");
    if (method == null) return;
    if (method.equals("pwdmodify")) { // 这个请求用的多,验证旧密码
      this.checkOldPassword(req, resp);
    } else if (method.equals("savepwd")) {
      this.updatePwd(req, resp);
    } else if (method.equals("query")) { // userList.jsp,用户管理
      this.query(req, resp);
    }
  }

  // 传递用户列表以及role列表
  private void query(HttpServletRequest req, HttpServletResponse resp)
      throws ServletException, IOException {
    // 前端需要的数据查询服务 dao-service都已经写好后,去jsp/js页面查看究竟传哪些过去,以及需要的参数
    // 当然这些参数都是在userList.jsp 查询/分页/跳转页面 传递过来的,如果是通过主页进去 userList.jsp,那么是没有这些参数的
    // 一般来说看表单中的 input标签的name知道传了什么进来
    // 看jsp中的额el表达式看需要传什么出去
    String userName = req.getParameter("queryname"); // 查询的用户名
    String role = req.getParameter("queryUserRole"); // 查询的role id
    String pageIndex = req.getParameter("pageIndex"); // 第几页

    List<User> userList = null;
    List<Role> roles = null;
    int pageSize =
        Integer.parseInt(getServletContext().getInitParameter("pageSize")); // context-param, 一页的数量
    Integer roleId = null, currentPageIndex = 1; // 默认role id = null, current = 第 1 页

    if (userName == null) userName = "";
    if (!StringUtils.isNullOrEmpty(role)) roleId = Integer.parseInt(role);
    if (!StringUtils.isNullOrEmpty(pageIndex)) currentPageIndex = Integer.parseInt(pageIndex);

    UserService userService = new UserServiceImpl();
    int totalCount = userService.getUserCount(userName, roleId); // 用户总数
    // 分页工具类,帮我计算页面信息
    PageSupport pageSupport = new PageSupport();
    // wow靠,贼坑，要先设置pageSize,再设置totalCount,要不然 pageSupport.java 57 line 出错
    pageSupport.setPageSize(pageSize);
    pageSupport.setTotalCount(totalCount); // 不小心设成了pageCount
    pageSupport.setCurrentPageNo(currentPageIndex);
    // 页码控制
    if (currentPageIndex < 1) currentPageIndex = 1;
    else if (currentPageIndex > totalCount) currentPageIndex = totalCount;

    userList = userService.getUserList(userName, roleId, currentPageIndex, pageSize); // 当前页用户列表
    req.setAttribute("userList", userList); // userList.jsp 43 line

    RoleService roleService = new RoleServiceImpl();
    roles = roleService.getRoleList();
    req.setAttribute("roleList", roles); // userList.jsp 17 line
    req.setAttribute("queryUserName", userName); // 13 line
    req.setAttribute("queryUserRole", roleId); // 21
    req.setAttribute("totalCount", totalCount); // 79 总记录数
    req.setAttribute("currentPageNo", currentPageIndex); // 80 当前页数
    req.setAttribute("totalPageCount", pageSupport.getTotalPageCount()); // 77 总页数

    // 转发去用户管理页面,写成userLis都t不行
    req.getRequestDispatcher("/jsp/userlist.jsp").forward(req, resp);
  }

  private void updatePwd(HttpServletRequest request, HttpServletResponse response) {
    // 通过session获得用户id
    User user = (User) request.getSession().getAttribute(Constants.USER_SESSION);
    String newpassword = request.getParameter("newpassword");
    boolean flag = false;
    /*错误信息,放在request.message(attr)中*/
    if (user != null && !StringUtils.isNullOrEmpty(newpassword)) { // 已登入并且密码不空
      UserService userService = new UserServiceImpl();
      flag = userService.updatePwd(user.getId(), newpassword); // 更新数据库
      if (flag) { // 成功
        /*狂神web视频中觉得修改后，跳转至一个提示页面，然后重新登陆（移除session）
        但我觉得不需要吧, 重新设置一下session即可*/
        request.setAttribute("message", "密码修改成功");
        user.setUserPassword(newpassword);
        request.getSession().setAttribute(Constants.USER_SESSION, user);

        /*// 密码修改成功,移除session(移除后不能再次修改密码,建议不移除)
        request.getSession().removeAttribute(Constants.USER_SESSION);*/
      } else {
        // 密码修改失败
        request.setAttribute("message", "密码修改失败");
      }
    } else {
      // session或新密码有问题
      request.setAttribute("message", "新密码有问题或者登陆状态失效");
    }
    try {
      // 转发
      request.getRequestDispatcher("/jsp/pwdmodify.jsp").forward(request, response);
    } catch (ServletException | IOException e) {
      e.printStackTrace();
    }
  }

  private void checkOldPassword(HttpServletRequest request, HttpServletResponse response) {
    Map<String, String> resultMap = new HashMap<>(); // 返回给前端的结果集
    User user = (User) request.getSession().getAttribute(Constants.USER_SESSION);
    String oldPassWord = request.getParameter("oldpassword");
    // put的键 - data.result,值看if-else的判断 in pwdmodify.js
    if (user == null) { // session过期或未登录
      resultMap.put("result", "sessionerror");
    } else if (StringUtils.isNullOrEmpty(request.getParameter("oldpassword"))) { // 密码空
      resultMap.put("result", "error");
    } else { // 验证密码
      String pwd = user.getUserPassword();
      if (pwd.equals(oldPassWord)) {
        resultMap.put("result", "true");
      } else {
        resultMap.put("result", "false");
      }
    }

    // 传递json给前端ajax
    try {
      response.setContentType("application/json");
      PrintWriter writer = response.getWriter();
      writer.write(JSONArray.toJSONString(resultMap)); // map->json, fastjosn(alibaba)
      writer.flush(); // 刷新一下
      writer.close();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

  @Override
  protected void doPost(HttpServletRequest req, HttpServletResponse resp)
      throws ServletException, IOException {
    doGet(req, resp);
  }
}
